﻿using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Linq;
using NHibernate.Type;
using Ornament.Domain;
using Ornament.MemberShip.Permissions;
using Ornament.NHibernates;

namespace Ornament.MemberShip.Dao.NHibernateImple
{
    public class ResourceDao : IResourceDao
    {
        public object Get(Type resourceType, string id)
        {
            if (resourceType == null)
                throw new ArgumentNullException("resourceType");
            if (id == null)
                throw new ArgumentNullException("id");
            if (typeof(string) == resourceType)
                return id;

            var idType = SessionManager.Instance.Config.NHConfiguration.GetClassMapping(resourceType).Identifier.Type;
            return Get(resourceType, ConvertIdFromStringValue(id, idType));

        }

        public object Get(Type resourceType, object id)
        {
            if (resourceType == null)
                throw new ArgumentNullException("resourceType");
            if (id == null)
                throw new ArgumentNullException("id");
            if (typeof(string) == resourceType)
                return id;
            return SessionManager.Instance.CurrentSession.Get(resourceType, id);
        }

        public object Load(Type resourceType, string id)
        {
            if (resourceType == null)
                throw new ArgumentNullException("resourceType");
            if (id == null)
                throw new ArgumentNullException("id");
            if (typeof(string) == resourceType)
                return id;

            var idType = SessionManager.Instance.Config.NHConfiguration.GetClassMapping(resourceType).Identifier.Type;
            return Load(resourceType, ConvertIdFromStringValue(id, idType));
        }

        public object Load(Type resourceType, object id)
        {
            if (resourceType == null)
                throw new ArgumentNullException("resourceType");
            if (id == null)
                throw new ArgumentNullException("id");
            return SessionManager.Instance.CurrentSession.Load(resourceType, id);
        }

        private static object ConvertIdFromStringValue(string id, IType type)
        {
            var idType = type as NullableType;
            if (idType == null)
                throw new OrnamentException("Resource's Id only support mapping from  NullableType in nhibernate.");
            return idType.FromStringValue(id);


        }
    }
}